home *** CD-ROM | disk | FTP | other *** search
- /* convers server - based on conversd written by DK5SG
- * ported to WNOS by DB3FL - 9109xx/9110xx
- * ported to NOS by PE1NMB - 920120
- * Mods by PA0GRI
- * Cleanup, and additional mods by WG7J
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <time.h>
- #include <ctype.h>
- #ifdef UNIX
- #include <sys/types.h>
- #include <sys/stat.h>
- #endif
- #ifdef MSDOS
- #include <io.h>
- #endif
- #include "global.h"
- #include "config.h"
- #include "mailbox.h"
- #include "netuser.h"
- #include "pktdrvr.h"
- #include "timer.h"
- #include "cmdparse.h"
- #include "usock.h"
- #include "socket.h"
- #include "session.h"
- #include "files.h"
- #include "commands.h"
-
- #ifdef CONVERS
-
- #define LINK 1
- #define space
-
-
-
- int Sconv = -1;
- char Chostname[CNAMELEN+1];
- void conv_incom __ARGS((int s,void *t,void *p));
-
- #ifdef space
- static char cnumber[] = "*** Channel numbers must be in the range 0..%d.\n";
- #else
- static char cnumber[] = "* range 0..%d.\n";
- #endif
-
- #define MAXCHANNEL 32767
- #define LINELEN 256
- #define MAX_WAITTIME (60*60*3)
- #define NAMELEN 10
-
- struct convection {
- int type; /* Connection type */
- #define CT_UNKNOWN 0
- #define CT_USER 1
- #define CT_HOST 2
- #define CT_CLOSED 3
- char name[NAMELEN+1]; /* Name of user or host */
- char host[NAMELEN+1]; /* Name of host where user is logged on */
- struct convection *via; /* Pointer to neighbor host */
- char *data; /* room for some personal data */
- int channel; /* Channel number */
- int32 time; /* Connect time */
- int locked; /* Set if mesg already sent */
- int fd; /* Socket descriptor */
- int flags; /* User flags */
- #define CLOSE_SOCK 1
- #define USE_SOUND 2
- char ibuf[LINELEN]; /* Input buffer */
- int received; /* Number of bytes received */
- int xmitted; /* Number of bytes transmitted */
- struct convection *next; /* Linked list pointer */
- };
-
- #define CM_UNKNOWN (1 << CT_UNKNOWN)
- #define CM_USER (1 << CT_USER)
- #define CM_HOST (1 << CT_HOST)
- #define CM_CLOSED (1 << CT_CLOSED)
-
- #define NULLCONNECTION ((struct convection *) 0)
-
- /* put this after declaration of "struct convection" or gcc has a conniption */
- #ifdef LINK
- struct proc *Linker;
- static void connect_permlinks __ARGS((int a,void *b,void *c));
- static void update_permlinks __ARGS((char *name,struct convection *cp));
- static void check_buffer_overload __ARGS((void));
- static int Allow_host __ARGS((int s));
- #endif
-
- static struct convection *convections;
-
- struct permlink {
- char name[NAMELEN+1]; /* Name of link */
- int32 addr; /* address to link to */
- struct convection *convection; /* Pointer to associated connection */
- int32 statetime; /* Time of last (dis)connect */
- int tries; /* Number of connect tries */
- int32 waittime; /* Time between connect tries */
- int32 retrytime; /* Time of next connect try */
- int fd; /* socket descriptor */
- struct permlink *next; /* Linked list pointer */
- };
- #define NULLPERMLINK ((struct permlink *) 0)
-
- struct filter_link {
- struct filter_link *next;
- int32 addr;
- };
- #define NULLFL ((struct filter_link *) 0)
-
- static struct filter_link *Filterlinks;
- static int FilterMode;
- static struct permlink *permlinks;
- extern char Ccall[AXALEN];
-
- static int docfilter __ARGS((int argc,char *argv[],void *p));
- static int dochostname __ARGS((int argc,char *argv[],void *p));
- static int dociface __ARGS((int argc,char *argv[],void *p));
- static int doconfcall __ARGS((int argc,char *argv[],void *p));
- static int doclink __ARGS((int argc,char *argv[],void *p));
- static int doct4 __ARGS((int argc,char *argv[],void *p));
- static int docmaxwait __ARGS((int argc,char *argv[],void *p));
- static int docmaxq __ARGS((int argc,char *argv[],void *p));
- static void set_personal __ARGS((struct convection *cp));
-
- static struct cmds DFAR Ccmds[] = {
- "filter", docfilter, 0, 0, NULLCHAR,
- "hostname", dochostname,0, 0, NULLCHAR,
- "interface",dociface, 0, 0, NULLCHAR,
- "maxwait", docmaxwait, 0, 0, NULLCHAR,
- "maxq", docmaxq, 0, 0, NULLCHAR,
- #ifdef AX25
- "mycall", doconfcall, 0, 0, NULLCHAR,
- #endif
- #ifdef LINK
- "link", doclink, 0, 0, NULLCHAR,
- #endif
- #ifdef AX25
- "t4", doct4, 0, 0, NULLCHAR,
- #endif
- NULLCHAR,
- };
-
- /* Multiplexer for top-level convers command */
- int
- #ifdef PROTOTYPES
- doconvers(int argc,char **argv,void *p)
- #else
- doconvers(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- #endif
- {
- return subcmd(Ccmds,argc,argv,p);
- }
-
- #ifdef AX25
- /* Display or change our AX.25 conference call */
- static int
- doconfcall(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- char tmp[AXBUF];
-
- if(argc < 2){
- tprintf("%s\n",pax25(tmp,Ccall));
- return 0;
- }
- if(setcall(Ccall,argv[1]) == -1)
- return -1;
- return 0;
- }
-
- int32 CT4init = 7200; /* 2 hours default */
-
- /* Set link redundancy timer */
- static int
- doct4(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setlong(&CT4init,"Conf. redundancy timer (sec)",argc,argv);
- }
- #endif /* AX25 */
-
- int32 CMaxwait = MAX_WAITTIME;
-
- /* Set maxwait time for timed out links */
- static int
- docmaxwait(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setlong(&CMaxwait,"Re-link max wait (sec)",argc,argv);
- }
-
- int32 CMaxQ = 5*1024L;
-
- /* Set maxwait time for timed out links */
- static int
- docmaxq(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setlong(&CMaxQ,"Max. Queue (bytes)",argc,argv);
- }
-
- static int
- dochostname(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- if(argc == 1)
- tprintf("%s\n",Chostname);
- else {
- strncpy(Chostname,argv[1],NAMELEN);
- Chostname[CNAMELEN] = '\0';
- }
- return 0;
- }
-
- static int
- docfilter(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int32 addr;
- struct filter_link *fl;
-
- if(argc == 1) {
- if(Filterlinks) {
- tprintf("Mode is: %s\n", FilterMode ? "Accept" : "Refuse");
- for(fl=Filterlinks;fl;fl=fl->next)
- tprintf("%s\n",inet_ntoa(fl->addr));
- }
- return 0;
- }
- if(!stricmp(argv[1],"mode")) {
- if(argc == 2)
- tprintf("Mode is: %s\n", FilterMode ? "Accept" : "Refuse");
- else {
- if(*argv[2] == 'a' || *argv[2] == 'A')
- FilterMode = 1;
- else
- FilterMode = 0;
- }
- return 0;
- }
- if((addr = resolve(argv[1])) == 0) {
- tprintf(Badhost,argv[1]);
- return 1;
- }
- /* check to see if we already have this in the list */
- for(fl=Filterlinks;fl;fl=fl->next)
- if(fl->addr == addr)
- return 0; /* already have this one ! */
-
- /* Seems like a new one */
- fl = (struct filter_link *)callocw(1,sizeof(struct filter_link));
- fl->addr = addr;
- fl->next = Filterlinks;
- Filterlinks = fl;
- return 0;
- }
-
- #ifdef LINK
- static int
- doclink(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- int32 addr;
- struct permlink *pl;
-
- if(argc == 1) {
- for(pl=permlinks;pl;pl=pl->next)
- tprintf("%10s: %s\n",pl->name,inet_ntoa(pl->addr));
- return 0;
- }
- if((addr = resolve(argv[1])) == 0) {
- tprintf(Badhost,argv[1]);
- return 1;
- }
- /* check to see if we already have a link to such animal,
- * this happens when we stop and restart the server - WG7J
- */
- for(pl=permlinks;pl;pl=pl->next)
- if(pl->addr == addr)
- return 1; /* already have this one ! */
-
- /* Seems like a new link ! Go add it */
- pl = (struct permlink *)callocw(1,sizeof(struct permlink ));
- pl->addr = addr;
- pl->next = permlinks;
- permlinks = pl;
- if(argc > 2) {
- strncpy(pl->name,argv[2],NAMELEN);
- update_permlinks(pl->name,NULLCONNECTION);
- } else
- strcpy(pl->name,"Unknown");
- if(!Linker)
- Linker = newproc("Clinker",1024,connect_permlinks,0,0,NULL,0);
-
- return 0;
- }
- #endif
-
- static int
- dociface(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setflag(argc,argv[1],IS_CONV_IFACE,argv[2]);
- }
-
- /* Stop convers server */
- int
- #ifdef PROTOTYPES
- conv0(int argc,char **argv,void *p)
- #else
- conv0(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- #endif
- {
- close_s(Sconv);
- Sconv = -1;
- return 0;
- }
-
- /* Start up convers server */
- int
- #ifdef PROTOTYPES
- conv1(int argc,char **argv,void *p)
- #else
- conv1(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- #endif
- {
- struct sockaddr_in lsocket;
- int s;
-
- if(Sconv != -1){
- return 0;
- }
- psignal(Curproc,0); /* Don't keep the parser waiting */
- chname(Curproc,"Convers listener");
-
- lsocket.sin_family = AF_INET;
- lsocket.sin_addr.s_addr = INADDR_ANY;
- lsocket.sin_port = (argc < 2) ? IPPORT_CONVERS : atoi(argv[1]);
-
- Sconv = socket(AF_INET,SOCK_STREAM,0);
- bind(Sconv,(char *)&lsocket,sizeof(lsocket));
- listen(Sconv,1);
- for(;;){
- if((s = accept(Sconv,NULLCHAR,(int *)NULL)) == -1)
- break; /* Service is shutting down */
- /* Low mem check now done in tcpin.c - WG7J */
- /* Spawn a server */
- if(newproc("conversd",2048,conv_incom,s,0,NULL,0) == NULLPROC)
- close_s(s);
- }
- #ifdef LINK
- if(Linker)
- killproc(Linker);
- #endif
- return 0;
- }
-
- static void
- #ifdef PROTOTYPES
- free_connection(register struct convection *cp)
- #else
- free_connection(cp)
- register struct convection *cp;
- #endif
- {
- register struct permlink *p;
-
- for(p = permlinks; p; p = p->next)
- if(p->convection == cp)
- p->convection = NULLCONNECTION;
- if(cp->flags & CLOSE_SOCK)
- close_s(cp->fd);
- free((char *) cp);
- }
-
- static void
- #ifdef PROTOTYPES
- free_closed_connections(void)
- #else
- free_closed_connections()
- #endif
- {
- register struct convection *cp,*p;
- time_t currtime;
-
- currtime = time(&currtime);
-
- for(p = NULLCONNECTION,cp = convections; cp; )
- if(cp->type == CT_CLOSED ||
- (cp->type == CT_UNKNOWN && cp->time + 300 < currtime)){
- if(p) {
- p->next = cp->next;
- free_connection(cp);
- cp = p->next;
- } else {
- convections = cp->next;
- free_connection(cp);
- cp = convections;
- }
- } else {
- p = cp;
- cp = cp->next;
- }
- }
-
- static void
- update_permlinks(name,cp)
- char *name;
- struct convection *cp;
- {
- register struct permlink *p;
- time_t currtime;
-
- for(p = permlinks; p; p = p->next)
- if(!strcmp(p->name,name)) {
- currtime = time(&currtime);
- p->convection = cp;
- p->statetime = currtime;
- p->tries = 0;
- p->waittime = 60;
- p->retrytime = currtime + p->waittime;
- }
- }
-
- static struct convection *
- #ifdef PROTOTYPES
- alloc_connection(int fd)
- #else
- alloc_connection(fd)
- int fd;
- #endif
- {
- register struct convection *cp;
- time_t currtime;
-
- currtime = time(NULL);
-
- cp = (struct convection *)callocw(1,sizeof(struct convection ));
- cp->fd = fd;
- cp->flags = CLOSE_SOCK+USE_SOUND; /* close on exit, by default */
- cp->time = currtime;
- cp->next = convections;
- convections = cp;
- return cp;
- }
-
- #ifdef LINK
- /* check the host links for backlogged data.
- * If larger then set threshold, kill the link.
- * WG7J, 930208
- */
- void check_buffer_overload(void) {
- struct convection *p;
- struct usock *up;
-
- /* check the size of the outstanding data buffers */
- for(p = convections; p; p = p->next)
- if( (p->type == CT_HOST) &&
- ((up = itop(p->fd)) != NULLUSOCK) &&
- (up->cb.tcb->sndcnt > CMaxQ) )
- reset_tcp(up->cb.tcb);
- }
-
- void
- connect_permlinks(a,b,c)
- int a;
- void *b;
- void *c;
- {
- int s;
- register struct permlink *p;
- struct sockaddr_in cport;
- time_t currtime;
-
- for(;;) {
- pause(15000L);
- for(p = permlinks; p; p = p->next) {
- currtime = time(&currtime);
- if(p->convection || p->retrytime > currtime)
- continue;
- p->tries++;
- p->waittime <<= 1;
- if(p->waittime > CMaxwait)
- p->waittime = CMaxwait;
- p->retrytime = p->waittime + currtime;
- cport.sin_family = AF_INET;
- cport.sin_port = IPPORT_CONVERS;
- cport.sin_addr.s_addr = p->addr; /* we've resolved this earlier */
- if((s = socket(AF_INET,SOCK_STREAM,0)) == -1)
- continue;
- if(connect(s,(char *)&cport,SOCKSIZE) == -1) {
- shutdown(s,2); /* to make sure it doesn't linger around */
- close_s(s); /* WG7J - 9207228 */
- continue;
- }
- p->fd = s;
- if(newproc("permlink",2048,conv_incom,s,0,NULL,0) == NULLPROC){
- shutdown(s,2); /* blow it out of the water :-) */
- close_s(s);
- }
- }
- check_buffer_overload();
- }
- }
- #endif
-
-
- static void
- #ifdef PROTOTYPES
- clear_locks(void)
- #else
- clear_locks()
- #endif
- {
- register struct convection *p;
-
- for(p = convections;p;p = p->next)
- p->locked = 0;
- }
-
- static void send_sounds(struct convection *p) {
- if(p->flags & USE_SOUND)
- p->xmitted += usputs(p->fd,"");
- }
-
- static void
- #ifdef PROTOTYPES
- send_user_change_msg(char *name,char *host,int oldchannel,int newchannel)
- #else
- send_user_change_msg(name,host,oldchannel,newchannel)
- char *name,*host;
- int oldchannel,newchannel;
- #endif
- {
- register struct convection *p;
-
- for(p = convections; p; p = p->next) {
- if(p->type == CT_USER && !p->via && !p->locked) {
- if(p->channel == oldchannel) {
- if(newchannel >= 0) {
- p->xmitted += usprintf(p->fd,
- "*** %s switched to channel %d.\n",
- name,newchannel);
- } else
- p->xmitted += usprintf(p->fd,
- "*** %s signed off.\n",name);
- p->locked = 1;
- }
- if(p->channel == newchannel) {
- send_sounds(p);
- p->xmitted += usprintf(p->fd,
- "*** %s signed on.\n",name);
- p->locked = 1;
- }
- }
- if(p->type == CT_HOST && !p->locked) {
- p->xmitted += usprintf(p->fd,
- "/\377\200USER %s %s %d %d %d\n",
- name,host,0,oldchannel,newchannel);
- p->locked = 1;
- }
- }
- return;
- }
-
- #ifdef Oldcode
-
- static char *
- formatline(prefix,text)
- char *prefix,*text;
- {
-
- #define PREFIXLEN 10
- #define CONVLINELEN 79
-
- register char *f,*t,*x;
- register int l,lw;
-
- static char buf[2*LINELEN];
-
- for(f = prefix,t = buf; *f; *t++ = *f++) ;
- l = (int)(t - buf);
- f = text;
-
- for(;;) {
- while(isspace(uchar(*f)))
- f++;
- if(!*f) {
- *t++ = '\n';
- *t = '\0';
- return buf;
- }
- for(x = f; *x && !isspace(uchar(*x)); x++) ;
- lw = (int)(x - f);
- if(l > PREFIXLEN && l + 1 + lw > CONVLINELEN) {
- *t++ = '\n';
- l = 0;
- }
- do {
- *t++ = ' ';
- l++;
- } while(l < PREFIXLEN);
- while(lw--) {
- *t++ = *f++;
- l++;
- }
- }
- }
-
- static void
- send_msg_to_user(fromname,toname,text)
- char *fromname,*toname,*text;
- {
- register struct convection *p;
- char buffer[2*LINELEN];
-
- for(p = convections; p; p = p->next) {
- if(p->type == CT_USER && !strcmp(p->name,toname))
- if(p->via) {
- if(!p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200UMSG %s %s %s\n",fromname,toname,text);
- p->via->locked = 1;
- }
- } else {
- if(!p->locked) {
- if(strcmp(fromname,"conversd")) {
- sprintf(buffer,"<*%s*>:",fromname);
- p->xmitted += usprintf(p->fd,"%s",formatline(buffer,text));
- } else {
- p->xmitted += usprintf(p->fd,"%s\n",text);
- }
- p->locked = 1;
- }
- }
- }
- return;
- }
-
- static void
- send_msg_to_channel(fromname,channel,text)
- char *fromname;
- int channel;
- char *text;
- {
- char buffer[3*LINELEN];
- register struct convection *p;
-
- for(p = convections; p; p = p->next) {
- if(p->type == CT_USER && p->channel == channel)
- if(p->via) {
- if(!p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200CMSG %s %d %s\n",fromname,channel,text);
- p->via->locked = 1;
- }
- } else {
- if(!p->locked) {
- sprintf(buffer,"<%s>:",fromname);
- p->xmitted += usprintf(p->fd,"%s",formatline(&buffer[0],text));
- p->locked = 1;
- }
- }
- }
- }
-
- #else /* Oldcode */
-
- /* Returns a formatted version of the given text.
- * The prefix appears at the beginning of the text, and each
- * line after the first will be indented to column PREFIXLEN.
- * All whitespace (SPACE and TAB) will be replaced by a single
- * SPACE character,
- * Lines will be filled to be CONVLINELEN characters long, wrapping
- * words as necessary.
- *
- * This uses an static internal buffer rather than one passed by
- * the caller. This increases the static memory used by the program
- * even if converse isn't active. If we passed a buffer allocated
- * on the stack, the process's stack would have to be large enough.
- */
- static char *
- #ifdef PROTOTYPES
- formatline(char *prefix, char *text)
- #else
- formatline(prefix, text)
- char *prefix, *text;
- #endif
- {
-
- # define PREFIXLEN 10
- # define CONVLINELEN 79
- # define FMTBUFLEN LINELEN
-
- static char buf[FMTBUFLEN];
- register char *f, *t;
- register int l, lw;
- register int left = FMTBUFLEN-2;
- /* Runs of characters in delims[] will be collapsed into a single
- space by formatline().
- */
- char *delims = " \t\n\r";
-
- # define BPUTC(c) do{ if (left > 0) { left--; *t++ = (c); }} while(0)
-
- /* Copy prefix into buf; set l to length of prefix.
- */
- l = 0;
- for (f = prefix, t = buf; *f; ) {
- BPUTC (*f++);
- l++;
- }
-
- f = text;
-
- for (;;) {
- /* Skip leading spaces */
- while (isspace(uchar(*f)))
- f++;
-
- /* Return if nothing more or no room left */
- if (!*f || (left <= 0)) {
- *t++ = '\n'; /* don't use BPUTC; do even if !left */
- *t = '\0';
- return buf;
- }
-
- /* Find length of next word (seq. of non-blanks) */
- lw = strcspn (f, delims);
-
- /* If the word would extend past end of line, do newline */
- if (l > PREFIXLEN && (l + 1 + lw) > CONVLINELEN) {
- BPUTC ('\n');
- l = 0;
- }
-
- /* Put out a single space */
- do {
- BPUTC (' ');
- l++;
- } while(l < PREFIXLEN);
-
- /* Put out the word */
- while(lw--) {
- BPUTC (*f++);
- l++;
- }
- }
- # undef BPUTC
- }
-
-
- static void
- #ifdef PROTOTYPES
- send_msg_to_user(char *fromname,char *toname,char *text)
- #else
- send_msg_to_user(fromname,toname,text)
- char *fromname,*toname,*text;
- #endif
- {
- register struct convection *p;
-
- for (p = convections; p; p = p->next) {
- if(p->type == CT_USER && !strcmp(p->name,toname))
- if(p->via) {
- if(!p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200UMSG %.10s %.10s %.220s\n",
- fromname, toname, text);
- p->via->locked = 1;
- }
- } else {
- if(!p->locked) {
- if(strcmp(fromname,"conversd")) {
- char prefix[NAMELEN+10];
- char *buf;
-
- sprintf(prefix,"<*%.10s*>:",fromname);
-
- buf = formatline (prefix,text);
- p->xmitted += strlen (buf);
- (void) usputs (p->fd, buf);
- } else { /* not from conversd */
- p->xmitted += strlen (text);
- (void) usputs (p->fd, text);
- } /* not from conversd */
- p->locked = 1;
- } /* if not locked */
- } /* not via */
- } /* for */
- }
-
- static void
- #ifdef PROTOTYPES
- send_msg_to_channel(char *fromname,int channel,char *text)
- #else
- send_msg_to_channel(fromname,channel,text)
- char *fromname;
- int channel;
- char *text;
- #endif
- {
- register struct convection *p;
-
- for (p = convections; p; p = p->next) {
- if(p->type == CT_USER && p->channel == channel)
- if(p->via) {
- if(!p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200CMSG %.10s %d %.220s\n",
- fromname, channel, text);
- p->via->locked = 1;
- }
- } else {
- if(!p->locked) {
- char prefix[NAMELEN+10];
- char *buf;
-
- sprintf(prefix,"<%.10s>:", fromname);
-
- buf = formatline (prefix, text);
- p->xmitted += strlen (buf);
- (void) usputs (p->fd, buf);
-
- p->locked = 1;
- } /* not locked */
- } /* not via */
- } /* for */
- }
-
-
- #endif /* Oldcode */
-
-
- extern char *Months[]; /* in smtpserv.c */
-
- static char *
- #ifdef PROTOTYPES
- timestring(long gmt)
- #else
- timestring(gmt)
- long gmt;
- #endif
- {
- static char buffer[10];
- struct tm *tm;
- time_t currtime;
-
- time(&currtime);
- tm = localtime(&gmt);
- if(gmt + 24 * 60 * 60 > currtime)
- sprintf(buffer," %2d:%02d",tm->tm_hour,tm->tm_min);
- else
- sprintf(buffer,"%-3.3s %2d",Months[tm->tm_mon],tm->tm_mday);
- return buffer;
- }
-
- #ifdef space
- char invitetext[] = "\n*** Message from %s at%s ...\nPlease join convers channel %d.\n\n";
- char mbinvitetext[] = "\n*** Message from %s at%s ...\nPlease type 'C' to join convers, then goto channel %d.\n\n";
- char responsetext[] = "*** Invitation sent to %s @ %s";
- #else
- char invitetext[] = "\n*** Msg frm %s at%s ...\nPse join ch. %d.\n\n";
- char mbinvitetext[] = "\n*** Msg frm %s at%s ...\nPse hit 'C' for convers; goto ch. %d.\n\n";
- char responsetext[] = "*** sent to %s @ %s";
- #endif
- char cnvd[] = "conversd";
-
- static void
- #ifdef PROTOTYPES
- send_invite_msg(char *fromname,char *toname,int channel)
- #else
- send_invite_msg(fromname,toname,channel)
- char *fromname,*toname;
- int channel;
- #endif
- {
-
- char buffer[LINELEN];
- struct convection *p;
- #ifdef MAILBOX
- struct mbx *m;
- #endif
- time_t currtime;
-
- currtime = time(&currtime);
-
- #ifdef MAILBOX
- /* Check users in the mailbox that aren't active */
- for(m=Mbox;m;m=m->next){
- if(m->state == MBX_CMD && !strcmp(m->name,toname)) {
- usprintf(m->user,mbinvitetext,fromname,timestring(currtime),channel);
- usflush(m->user);
- clear_locks();
- sprintf(buffer,responsetext,toname,"BBS@");
- strcat(buffer,Hostname);
- send_msg_to_user(cnvd,fromname,buffer);
- return;
- }
- }
- #endif
-
- /* check the current convers users */
- for(p = convections; p; p = p->next) {
- if(p->type == CT_USER && !strcmp(p->name,toname)) {
- if(p->channel == channel) {
- clear_locks();
- sprintf(buffer,"*** User %s is already on this channel.\n",toname);
- send_msg_to_user(cnvd,fromname,buffer);
- return;
- }
- if(!p->via && !p->locked) {
- p->xmitted += usprintf(p->fd,invitetext,fromname, \
- timestring(currtime),channel);
- clear_locks();
- sprintf(buffer,responsetext,toname,Chostname);
- send_msg_to_user(cnvd,fromname,buffer);
- return;
- }
- if(p->via && !p->via->locked) {
- p->via->xmitted += usprintf(p->via->fd,
- "/\377\200INVI %s %s %d\n",fromname,toname,channel);
- return;
- }
- }
- }
- /* Nothing found locally, invite user on all links */
- for(p = convections; p; p = p->next) {
- if(p->type == CT_HOST && !p->locked) {
- p->xmitted += usprintf(p->fd,
- "/\377\200INVI %s %s %d\n",fromname,toname,channel);
- }
- }
- return;
- }
-
- static void
- #ifdef PROTOTYPES
- bye_command(struct convection *cp)
- #else
- bye_command(cp)
- struct convection *cp;
- #endif
- {
- register struct convection *p;
-
- switch(cp->type) {
- case CT_UNKNOWN:
- cp->type = CT_CLOSED;
- break;
- case CT_USER:
- cp->type = CT_CLOSED;
- clear_locks();
- send_user_change_msg(cp->name,cp->host,cp->channel,-1);
- break;
- case CT_HOST:
- cp->type = CT_CLOSED;
- update_permlinks(cp->name,NULLCONNECTION);
- for(p = convections; p; p = p->next)
- if(p->via == cp) {
- p->type = CT_CLOSED;
- clear_locks();
- send_user_change_msg(p->name,p->host,p->channel,-1);
- }
- break;
- case CT_CLOSED:
- break;
- }
- }
-
- static void
- #ifdef PROTOTYPES
- channel_command(struct convection *cp)
- #else
- channel_command(cp)
- struct convection *cp;
- #endif
- {
- char s[7];
- int newchannel;
-
- s[0] = '\0';
- sscanf(cp->ibuf,"%*s %6s",s);
- if(s[0] == '\0') {
- #ifdef space
- cp->xmitted += usprintf(cp->fd,"*** You are on channel %d.\n",cp->channel);
- #else
- cp->xmitted += usprintf(cp->fd,"* On channel %d.\n",cp->channel);
- #endif
- return;
- }
- newchannel = atoi(s);
- if(newchannel < 0) {
- /* || newchannel > MAXCHANNEL) { */
- cp->xmitted += usprintf(cp->fd,cnumber,MAXCHANNEL);
- return;
- }
- if(newchannel == cp->channel) {
- cp->xmitted += usprintf(cp->fd,
- "*** Already on channel %d.\n",cp->channel);
- return;
- }
- send_user_change_msg(cp->name,cp->host,cp->channel,newchannel);
- cp->channel = newchannel;
- cp->xmitted += usprintf(cp->fd,"*** Now on channel %d.\n",cp->channel);
- return;
- }
-
- static void
- #ifdef PROTOTYPES
- help_command(struct convection *cp)
- #else
- help_command(cp)
- struct convection *cp;
- #endif
- {
- #ifdef space
- cp->xmitted += usprintf(cp->fd,"Commands may be abbreviated. Commands are:\n");
- cp->xmitted += usprintf(cp->fd,"/? or /HELP\t\tPrint help information\n");
- cp->xmitted += usprintf(cp->fd,"/BYE\t\t\tTerminate the convers session\n");
- cp->xmitted += usprintf(cp->fd,"/CHANNEL n\t\tSwitch to channel n\n");
- cp->xmitted += usprintf(cp->fd,"/EXIT\t\t\tTerminate the convers session\n");
- cp->xmitted += usprintf(cp->fd,"/INVITE user\t\tInvite user to join your channel\n");
- cp->xmitted += usprintf(cp->fd,"/LINKS [LONG]\t\tList all connections to other hosts\n");
- cp->xmitted += usprintf(cp->fd,"/MSG user text...\tSend a private message to user\n");
- cp->xmitted += usprintf(cp->fd,"/PERSONAL text\t\tSet or show some personal text\n");
- cp->xmitted += usprintf(cp->fd,"/QUIT\t\t\tTerminate the convers session\n");
- cp->xmitted += usprintf(cp->fd,"/SOUNDS y|n\t\tTurn bell on or off\n");
- cp->xmitted += usprintf(cp->fd,"/WHO [QUICK]\t\tList all users and their channel numbers\n");
- cp->xmitted += usprintf(cp->fd,"/WRITE user text...\tSend a private message to user\n***\n");
- #else
- cp->xmitted += usprintf(cp->fd,"no help\n");
- #endif
- return;
- }
-
- static void
- #ifdef PROTOTYPES
- invite_command(struct convection *cp)
- #else
- invite_command(cp)
- struct convection *cp;
- #endif
- {
- char toname[NAMELEN+1];
- char *cp1;
-
- toname[0] = '\0';
- sscanf(cp->ibuf,"%*s %10s",toname);
- if((cp1=strchr(toname,'@')) != NULLCHAR)
- *cp1 = '\0';
- if(toname[0] != '\0')
- send_invite_msg(cp->name,toname,cp->channel);
- return;
- }
-
- int ShowConfLinks(int s, int full) {
- int num;
- struct convection *pc;
- struct permlink *pp;
- char tmp[20];
-
- num = usprintf(s,"Host State Since%s\n",
- (full) ? " NextTry Tries Receivd Xmitted" : "");
- for(pc = convections; pc; pc = pc->next)
- if(pc->type == CT_HOST)
- num += usprintf(s,
- (full) ?
- "%-10s Connected %s %7d %7d\n" :
- "%-10s Connected %s\n",
- pc->name,
- timestring(pc->time),
- pc->received,
- pc->xmitted);
-
- for(pp = permlinks; pp; pp = pp->next)
- if(!pp->convection || pp->convection->type != CT_HOST) {
- strcpy(tmp,timestring(pp->retrytime));
- num += usprintf(s,
- (full) ?
- "%-10s %-12s %s %s %5d\n" :
- "%-10s %-12s %s\n",
- pp->name,
- pp->convection ? "Connecting" : "Disconnected",
- timestring(pp->statetime),
- tmp,
- pp->tries);
- }
- num += usprintf(s,"***\n");
- return num;
- }
-
- static void
- #ifdef PROTOTYPES
- links_command(struct convection *cp)
- #else
- links_command(cp)
- struct convection *cp;
- #endif
- {
- char full[3];
- int f = 0;
-
- full[0] = '\0';
- sscanf(cp->ibuf,"%*s %2s",full);
- if(*full == 'l' || *full == 'L')
- f = 1;
- cp->xmitted += ShowConfLinks(cp->fd,f);
- return;
- }
-
- static void
- #ifdef PROTOTYPES
- msg_command(struct convection *cp)
- #else
- msg_command(cp)
- struct convection *cp;
- #endif
- {
-
- char dummy[LINELEN],toname[NAMELEN+1],*text;
- register struct convection *p;
-
- toname[0] = '\0';
- sscanf(cp->ibuf,"%s %10s",dummy,toname);
- text = &cp->ibuf[0];
- text += strlen(dummy) + strlen(toname) + 2;
-
- if(!*text)
- return;
- for(p = convections; p; p = p->next)
- if(p->type == CT_USER && !strcmp(p->name,toname))
- break;
- if(!p)
- cp->xmitted += usprintf(cp->fd,"*** No such user: %s.\n",toname);
- else
- send_msg_to_user(cp->name,toname,text);
- return;
- }
-
- /* Set some personal data, like name and qth - WG7J */
- static void
- #ifdef PROTOTYPES
- personal_command(struct convection *cp)
- #else
- personal_command(cp)
- struct convection *cp;
- #endif
- {
- struct convection *p;
- char *cp2;
-
- if((cp2 = strchr(cp->ibuf,' ')) != NULLCHAR) {
- cp2++;
- if(*cp2) { /* there actually is an argument */
- if(cp->data)
- free(cp->data);
- rip(cp->ibuf); /* get rid of ending '\n' */
- cp->data = strdup(cp2);
- /* update all links too ! - WG7J */
- for(p=convections;p;p=p->next)
- if(p->type == CT_HOST)
- p->xmitted += usprintf(p->fd,"/\377\200UDAT %s %s %s\n",
- cp->name,cp->host,cp->data);
- return;
- }
- }
- cp->xmitted += usprintf(cp->fd,"*** data set to: %s\n", \
- cp->data ? cp->data : "" );
- return;
- }
-
- /* find the personal information for this user */
- void set_personal(struct convection *cp) {
- FILE *fp;
- char *cp1;
-
- if((fp = fopen(Cinfo,"r")) == NULL)
- return;
- while(fgets(cp->ibuf,LINELEN,fp) != NULL) {
- cp1 = cp->ibuf;
- /* find end of name */
- while(*cp1 != ' ' && *cp1 != '\t' && *cp1 != '\0')
- cp1++;
- if(!*cp1)
- continue;
- *cp1 = '\0';
- if(stricmp(cp->name,cp->ibuf))
- continue;
- /* Found personal data ! */
- *cp1 = ' ';
- fclose(fp);
- personal_command(cp);
- return;
- }
- fclose(fp);
- }
-
- /* protected by ftpusers file - WG7J */
- static void
- #ifdef PROTOTYPES
- name_command(struct convection *cp)
- #else
- name_command(cp)
- struct convection *cp;
- #endif
- {
- int newchannel;
- char dummy[7];
- char *path;
- int pwdignore;
- long privs;
-
- cp->name[0] = '\0';
- dummy[0] = '\0';
- sscanf(cp->ibuf,"%*s %10s %6s",cp->name,dummy);
- newchannel = atoi(dummy);
- if(cp->name[0] == '\0')
- return;
- /* now check with ftpusers file - WG7J */
- if((path = mallocw(MBXLINE)) == NULLCHAR)
- return;
- pwdignore = 1;
- privs = userlogin(cp->name,NULLCHAR,&path,MBXLINE,&pwdignore);
- free(path);
- if(privs & NO_CONVERS)
- return;
- strlwr(cp->name);
- strcpy(cp->host,Chostname);
- cp->type = CT_USER;
- cp->xmitted += usprintf(cp->fd,
- "Conference @ %s Type /HELP for help.\n",Chostname);
- if(newchannel < 0) {
- /* || newchannel > MAXCHANNEL) { */
- cp->xmitted += usprintf(cp->fd,cnumber,MAXCHANNEL);
- } else
- cp->channel = newchannel;
- send_user_change_msg(cp->name,cp->host,-1,cp->channel);
- set_personal(cp);
- return;
- }
-
- /* Set or show the status of the 'sound' flag - WG7J */
- static void
- #ifdef PROTOTYPES
- sounds_command(struct convection *cp)
- #else
- sounds_command(cp)
- struct convection *cp;
- #endif
- {
- char *cp2;
-
- if((cp2 = strchr(cp->ibuf,' ')) != NULLCHAR) {
- cp2++;
- if(*cp2) { /* There is an argument */
- if(*cp2 == 'n' || *cp2 == 'N') { /* Turn it off */
- cp->flags &= ~USE_SOUND;
- } else
- cp->flags |= USE_SOUND;
- return;
- }
- }
- if(cp->flags & USE_SOUND)
- usputs(cp->fd,"*** Sounds on\n");
- else
- usputs(cp->fd,"*** Sounds off\n");
- return;
- }
-
- /* Print a user display, return the number of characters sent */
- int ShowConfUsers(int s,int quick) {
- int num,channel;
- struct convection *p;
- char buffer[LINELEN];
- #ifdef MAILBOX
- struct mbx *m;
- #endif
-
- if(quick) {
- num = usprintf(s,"Channel Users\n");
- clear_locks();
- do {
- channel = -1;
- for(p = convections; p; p = p->next) {
- if(p->type == CT_USER &&
- !p->locked &&
- (channel < 0 || channel == p->channel)) {
- if(channel < 0) {
- channel = p->channel;
- sprintf(buffer,"%7d",channel);
- }
- strcat(buffer," ");
- strcat(buffer,p->name);
- p->locked = 1;
- }
- }
- if(channel >= 0) {
- num += usprintf(s,"%s\n",buffer);
- }
- } while(channel >= 0);
- } else {
- num = usprintf(s,"User Host Via Channel Time Personal\n");
- for(p = convections; p; p = p->next) {
- if(p->type == CT_USER) {
- num += usprintf(s,"%-10s %-10s %-10s %7d %s %s\n",
- p->name,
- p->host,
- p->via ? p->via->name : "",
- p->channel,
- timestring(p->time),
- p->data ? p->data : "" );
- }
- }
- }
- #ifdef MAILBOX
- for(m=Mbox;m;m=m->next) {
- if(m->state == MBX_CMD) {
- if(quick)
- num += usprintf(s," BBS %s\n",m->name);
- else
- num += usprintf(s,"%-10s BBS@%s\n",m->name,Hostname);
- }
- }
- #endif
- num += usprintf(s,"***\n");
- return num;
- }
-
- static void
- #ifdef PROTOTYPES
- who_command(struct convection *cp)
- #else
- who_command(cp)
- struct convection *cp;
- #endif
- {
- char buffer[LINELEN];
- int quick = 0;
-
- buffer[0] = '\0';
- sscanf(cp->ibuf,"%*s %2s",buffer);
- switch(tolower(buffer[0])) {
- case 'q':
- quick = 1;
- break;
- }
- cp->xmitted += ShowConfUsers(cp->fd,quick);
- return;
- }
-
- static void
- #ifdef PROTOTYPES
- h_cmsg_command(struct convection *cp)
- #else
- h_cmsg_command(cp)
- struct convection *cp;
- #endif
- {
- char *text;
- int channel;
- char name[LINELEN],dummy[40];
-
- sscanf(cp->ibuf,"%s %10s %d",dummy,name,&channel);
- text = &cp->ibuf[0];
- text += strlen(dummy) + strlen(name) + 2;
- while(isspace(*text) == 0)
- text++;
- text++;
- if(isprint(*text) != 0)
- send_msg_to_channel(name,channel,text);
- return;
- }
-
- /* Return 1 if the host is to be allowed, or 0 if refused - WG7J */
- int Allow_host(int s) {
- struct filter_link *fl;
- struct sockaddr_in fsocket;
- int i = sizeof(struct sockaddr_in);
-
- if(Filterlinks) { /* Check for this ip address */
- getpeername(s,(char *)&fsocket,&i);
- for(fl=Filterlinks;fl;fl=fl->next)
- if(fl->addr == fsocket.sin_addr.s_addr)
- return FilterMode;
- /* Not found ! */
- return !FilterMode;
- }
- return 1;
- }
-
- static void
- #ifdef PROTOTYPES
- h_host_command(struct convection *cp)
- #else
- h_host_command(cp)
- struct convection *cp;
- #endif
- {
-
- char name[NAMELEN+1];
- struct convection *p;
- struct permlink *pp;
-
- if(!Allow_host(cp->fd)) {
- bye_command(cp);
- return;
- }
- name[0] = '\0';
- sscanf(cp->ibuf,"%*s %10s",name);
- if(name[0] == '\0') {
- bye_command(cp);
- return;
- }
- for(p = convections; p; p = p->next)
- if(!strcmp(p->name,name)) {
- bye_command(p);
- return;
- }
- for(pp = permlinks; pp; pp = pp->next)
- if(!strcmp(pp->name,name) && pp->convection && pp->convection != cp) {
- bye_command((strcmp(Chostname,name) < 0) ? pp->convection : cp);
- return;
- }
- /*
- if(cp->type != CT_UNKNOWN)
- return;
- */
- cp->type = CT_HOST;
- strcpy(cp->name,name); /* already allocated */
- update_permlinks(name,cp);
- cp->xmitted += usprintf(cp->fd,"/\377\200HOST %s\n",Chostname);
- for(p = convections; p; p = p->next)
- if(p->type == CT_USER) {
- cp->xmitted += usprintf(cp->fd,
- "/\377\200USER %s %s %d %d %d\n",
- p->name,p->host,0,-1,p->channel);
- if(p->data)
- cp->xmitted += usprintf(cp->fd,
- "/\377\200UDAT %s %s %s\n",
- p->name,p->host,p->data);
- }
- return;
- }
-
- static void
- #ifdef PROTOTYPES
- h_invi_command(struct convection *cp)
- #else
- h_invi_command(cp)
- struct convection *cp;
- #endif
- {
- char fromname[NAMELEN+1],toname[NAMELEN+1];
- int channel;
-
- sscanf(cp->ibuf,"%*s %10s %10s %d",fromname,toname,&channel);
- send_invite_msg(fromname,toname,channel);
- return;
- }
-
- static void
- #ifdef PROTOTYPES
- h_loop_command(struct convection *cp)
- #else
- h_loop_command(cp)
- struct convection *cp;
- #endif
- {
- char host[NAMELEN+1];
-
- sscanf(cp->ibuf,"%*s %10s",host);
- log(cp->fd, "conversd rx: LOOP %s",host);
- bye_command(cp);
- }
-
- /* Command to take user's personal data across a link - WG7J */
- static void
- #ifdef PROTOTYPES
- h_udat_command(struct convection *cp)
- #else
- h_udat_command(cp)
- struct convection *cp;
- #endif
- {
- char *name,*host,*data;
- struct convection *p;
-
- /* do a validity check first */
- if((name = strchr(cp->ibuf,' ')) == NULLCHAR)
- return;
- name++;
- if((host = strchr(name,' ')) == NULLCHAR)
- return;
- *host++ = '\0';
- if((data = strchr(host,' ')) == NULLCHAR)
- return;
- *data++ = '\0';
- rip(data); /* rip the '\n' */
- if(strlen(data) == 0)
- return;
- /* everything seems fine, now find user ! */
- for(p=convections;p;p=p->next) {
- if(!strcmp(p->name,name) && !strcmp(p->host,host)) {
- if(p->data)
- free(p->data);
- p->data = strdup(data);
- }
- /* update over other links Apr 12/93 VE3DTE */
- if(p->type == CT_HOST && !p->locked)
- p->xmitted += usprintf(p->fd, "/\377\200UDAT %s %s %s\n",
- name,host,data);
- }
- }
-
- static void
- #ifdef PROTOTYPES
- h_umsg_command(struct convection *cp)
- #else
- h_umsg_command(cp)
- struct convection *cp;
- #endif
- {
- char dummy[NAMELEN+1],fromname[NAMELEN+1],toname[NAMELEN+1],*text;
-
- sscanf(cp->ibuf,"%s %10s %10s",dummy,fromname,toname);
- text = &cp->ibuf[0];
- text += strlen(dummy) + strlen(fromname) + strlen(toname) + 3;
- if(*text)
- send_msg_to_user(fromname,toname,text);
- return;
- }
-
- static void
- #ifdef PROTOTYPES
- h_user_command(struct convection *cp)
- #else
- h_user_command(cp)
- struct convection *cp;
- #endif
- {
- char host[NAMELEN+1],name[NAMELEN+1];
- int newchannel,oldchannel;
- register struct convection *p;
- time_t currtime;
-
- currtime = time(&currtime);
-
- sscanf(cp->ibuf,"%*s %10s %10s %*s %d %d",name,host,&oldchannel,&newchannel);
-
- for(p = convections; p; p = p->next)
- if(p->type == CT_USER) {
- /* new 920705 dl9sau */
- /* If Neighbour2 registers a user on HostX, while someone has already
- * been registered for HostX via Neighbour1, then we definitely have
- * a loop ! We send a loop detect message and then close the link:
- * /..LOOP <Chostname> <myneighbour> <host>
- *
- * The LOOP PREVENTION CODE detects ONLY a loop if it starts at this
- * host. That's, why I suggest this code to be implemented in every
- * conversd implementation.
- */
- if (oldchannel < 0 && p->via != cp && !stricmp(p->host, host)) {
- usprintf(cp->fd,"/\377\200LOOP %s %s %s\n", \
- Chostname, host,p->via ? p->via->name : Chostname);
- log(cp->fd, "conversd sent: LOOP %s",host);
- bye_command(cp);
- return;
- }
- if(p->channel == oldchannel && p->via == cp && \
- !strcmp(p->name,name) && !strcmp(p->host,host))
- break;
- }
- if(!p) {
- p = (struct convection *)callocw(1,sizeof(struct convection ));
- p->type = CT_USER;
- strcpy(p->name,name);
- strcpy(p->host,host);
- p->via = cp;
- p->channel = oldchannel;
- p->time = currtime;
- p->next = convections;
- convections = p;
- }
- if((p->channel = newchannel) < 0) {
- p->type = CT_CLOSED;
- free_closed_connections(); /* VE3DTE Apr 5/93 */
- }
- send_user_change_msg(name,host,oldchannel,newchannel);
- return;
- }
-
- struct cmdtable {
- char *name;
- void (*fnc) __FARGS((struct convection *));
- int states;
- };
- struct cmdtable DFAR cmdtable[] = {
- "?", help_command, CM_USER,
- "bye", bye_command, CM_USER,
- "channel", channel_command, CM_USER,
- "exit", bye_command, CM_USER,
- "help", help_command, CM_USER,
- "invite", invite_command, CM_USER,
- "links", links_command, CM_USER,
- "msg", msg_command, CM_USER,
- "name", name_command, CM_UNKNOWN,
- "personal", personal_command, CM_USER,
- "quit", bye_command, CM_USER,
- "sounds", sounds_command, CM_USER,
- "who", who_command, CM_USER,
- "write", msg_command, CM_USER,
-
- "\377\200cmsg", h_cmsg_command, CM_HOST,
- "\377\200host", h_host_command, CM_UNKNOWN,
- "\377\200invi", h_invi_command, CM_HOST,
- "\377\200loop", h_loop_command, CM_HOST,
- "\377\200udat", h_udat_command, CM_HOST,
- "\377\200umsg", h_umsg_command, CM_HOST,
- "\377\200user", h_user_command, CM_HOST,
- 0, 0, 0,
- };
-
- static void
- #ifdef PROTOTYPES
- process_commands(struct convection *cp,struct mbx *m)
- #else
- process_commands(cp,m)
- struct convection *cp;
- struct mbx *m;
- #endif
- {
- char arg[LINELEN];
- int arglen,size;
- char *ccp;
- struct cmdtable *cmdp;
-
- for(;;) {
- loop:
- if(cp->type == CT_CLOSED)
- break;
- #ifdef MBXTDISC
- if(m) {
- /* Restart the inactivity timer - WG7J */
- start_timer(&m->tdisc);
- }
- #endif
- usflush(cp->fd);
- memset(cp->ibuf,0,sizeof(cp->ibuf));
- if((size = recvline(cp->fd,cp->ibuf,sizeof(cp->ibuf)-1)) <= 0)
- break;
- cp->received += size;
- clear_locks();
- cp->locked = 1;
- if(*cp->ibuf == '/') {
- ccp = &cp->ibuf[1];
- arg[0] = '\0';
- sscanf(ccp,"%s",arg);
- arglen = strlen(arg);
- /* We are about to parse a command; most likely there
- * is alot of output; try to avoid fragmenting that
- * data by doing our own flushing ! - WG7J
- */
- setflush(cp->fd,-1);
- for(cmdp = cmdtable; cmdp->name; cmdp++) {
- if(!strncmpi(cmdp->name,arg,(size_t)arglen)) {
- if(cmdp->states & (1 << cp->type))
- (*cmdp->fnc)(cp);
- setflush(cp->fd,'\n');
- goto loop;
- }
- }
- if(cp->type == CT_USER)
- cp->xmitted += usprintf(cp->fd,
- "*** Unknown command '/%s'. Type /HELP for help.\n",arg);
- setflush(cp->fd,'\n');
- goto loop;
- }
- if((ccp = strpbrk(cp->ibuf,"\r\n")) != NULLCHAR)
- *ccp = '\0';
- if(isprint(cp->ibuf[0]) != 0 && cp->type == CT_USER)
- send_msg_to_channel(cp->name,cp->channel,cp->ibuf);
- }
- sockblock(cp->fd,SOCK_BLOCK);
- bye_command(cp);
- free_closed_connections();
- }
-
- /* Incoming convers session */
- void
- conv_incom(s,t,p)
- int s;
- void *t;
- void *p;
- {
- struct convection *cp;
- struct permlink *pl;
-
- sockowner(s,Curproc); /* We own it now */
- sockmode(s,SOCK_BINARY);
- sockblock(s,SOCK_NOTXBLOCK); /* prevent backlogs ! */
- cp = alloc_connection(s);
-
- for(pl = permlinks; pl; pl = pl->next)
- if(pl->fd == s) {
- pl->convection = cp;
- cp->xmitted += usprintf(s,"/\377\200HOST %s\n",Chostname);
- }
-
- if(pl == NULLPERMLINK) {
- usprintf(cp->fd,"\npse login with '/n <call>'\n\n");
- }
- process_commands(cp,NULLMBX);
- }
-
- #ifdef MAILBOX
- #ifdef MBXTDISC
- extern int32 Mbtdiscinit;
- #endif
-
- /* this is for Mailbox users */
- void
- mbox_converse(m)
- struct mbx *m;
- {
- struct convection *cp;
-
- sockblock(m->user,SOCK_NOTXBLOCK); /* prevent backlogs ! */
- setflush(m->user,'\n'); /* automatic line flushing */
- cp = alloc_connection(m->user);
- strcpy(cp->name,m->name);
- strcpy(cp->host,Chostname);
- cp->type = CT_USER;
- cp->flags &= ~CLOSE_SOCK; /* do not close socket on exit */
- cp->xmitted += usprintf(m->user,
- "Conference @ %s Type /HELP for help.\n",Chostname);
- clear_locks();
- cp->locked = 1; /* send to everyone but ourself */
- send_user_change_msg(cp->name,cp->host,-1,0);
- set_personal(cp);
-
- #ifdef MBXTDISC
- /* Set the timeout timer to the convers t4 value */
- stop_timer(&m->tdisc);
- set_timer(&m->tdisc,CT4init * 1000L);
- start_timer(&m->tdisc);
- #endif
-
- process_commands(cp,m);
-
- setflush(m->user,-1);
- #ifdef MBXTDISC
- /* Reset to the mailbox timeout value */
- stop_timer(&m->tdisc);
- set_timer(&m->tdisc,Mbtdiscinit * 1000L);
- start_timer(&m->tdisc);
- #endif
-
- }
- #endif /* MAILBOX */
-
- #endif /* CONVERS */
-